import { FeatureType, ModeType } from '../types';
import { select } from 'd3-selection';
import Feature from '../feature/feature';
import DrawTip from '../ui/drawTip';
import Line from '../feature/line';
import Vertex from '../feature/vertex';
import Polygon from '../feature/polygon';

/**
 * 模式类
 */
class Mode {
    private type: ModeType; // draw,select,browse
    private featureType?: FeatureType; // draw模式下才需要有值
    selectedFeature?: Feature;
    drawTip?: DrawTip;
    drawFeature?: Feature | null;

    constructor() {
        this.type = 'browse';
    }

    /**
     * 改变模式，要改变surface的className
     * @param type draw,select,browse
     * @param featureType  point line polygon
     * @param feature 要素
     */
    enter(type: ModeType, featureType?: FeatureType, feature?: Feature) {
        const wrap = select('#seditor');

        // 清除上次模式的className,draw模式的className为mode-[modeType]_[featureType]
        wrap.classed(this.getClassName(this.type, this.featureType), false);
        wrap.classed(this.getClassName(type, featureType), true);

        // 选中模式下的类名处理
        if (type == 'select' && feature) {
            if (this.type == 'select' && this.selectedFeature) {
                // 移除上次选中
                this.changeSelectFeatureAttr(this.selectedFeature, false);
            }
            this.selectedFeature = feature;
            this.changeSelectFeatureAttr(feature, true);

            // 浏览模式下，取消选中要素的类名
        } else if (type == 'browse' || type === 'draw') {
            if (this.selectedFeature) {
                // 移除上次选中
                this.changeSelectFeatureAttr(this.selectedFeature, false);
                this.selectedFeature = undefined;
            }
        }

        // 移除标绘提示框
        if (this.drawTip) {
            this.drawTip.remove();
        }

        if (type == 'draw') {
            // 当前处于标绘模式，创建标绘提示框
            const text = featureType == 'point' ? '单击进行标点' : '单击确定地点，双击结束绘制';
            this.drawTip = new DrawTip(text);
        }

        this.type = type;
        this.featureType = featureType;
    }

    changeSelectFeatureAttr(feature: Feature, status: boolean) {
        feature.group.classed('selected', status);
        if (feature.type === 'line' || feature.type === 'polygon') {
            (feature as Line | Polygon).changeMidVertexVisible(status);
        } else if (feature.type === 'node') {
            for (const relate of (feature as Vertex).relateFeatures) {
                (relate as Line | Polygon).changeMidVertexVisible(status);
                if (relate.type === 'polygon') {
                    relate.group.classed('none-event', status);
                }
            }
        }
    }

    setDrawFeature(feature: Feature | null) {
        this.drawFeature = feature;
    }

    getClassName(type: string, featureType?: FeatureType) {
        return 'mode-' + type + (featureType ? '_' + featureType : '');
    }

    exit() {
        this.enter('browse');
    }

    getType() {
        return this.type;
    }

    getFeatureType() {
        return this.featureType;
    }
}

export default Mode;
